package main

import (
	"fmt"
)

/*
√ 封装人，属性包括姓名、年龄、身高、体重、颜值、资产、性别、性取向
√ 给人封装结婚方法，参数是潜在的结婚对象：
    ①如果对方的性取向有问题，panic
    ②如果对方的颜值过低，返回错误
    ③否则返回满意程度
*/

/*性别枚举*/
type Gender int

func (g Gender) String() string {
	return []string{"Male", "Female", "Bisexual"}[g]
}

const (
	//男的
	Male = iota
	//女的
	Female
	//二椅子
	Bisexual
)

/*不理想配偶错误*/
type BadSpouseError struct {
	why string
}

func (bse *BadSpouseError) Error() string {
	return bse.why
}

/*
判断ta是否理想配偶
如果ta棒棒的，返回nil
如果ta不给力，返回【非理想配偶错误】
*/
func CheckIfGood(ta *Human) *BadSpouseError {
	bse := new(BadSpouseError)
	if ta.Rmb < 1e6 {
		bse.why = "太穷"
	} else if ta.Weight > 200 {
		bse.why = "太胖"
	} else if ta.Age > 50 {
		bse.why = "太老"
	} else {
		//棒棒的，直接反nil——无可吐槽！
		return nil
	}
	return bse
}

type Human struct {
	Name   string
	Age    float64
	Height float64
	Weight float64
	Rmb    float64

	//自己的颜值和要求的颜值
	Looking       float64
	TargetLooking float64

	//自己的性别
	Sex Gender
	//结婚的目标性别
	TargetSex Gender
}

/*
结婚方法
ta *Human 潜在的结婚对象
happiness float64 结婚成功时返回幸福程度
err error 牵手失败时返回一个错误接口实例（实际上返回一个*BadSpouseError实例）
*/
func (h *Human) Marry(ta *Human) (happiness float64, err error) {
	/*如果对方的性取向有问题，panic*/
	if ta.Sex != h.TargetSex {
		panic(&BadSpouseError{"性别不符合要求"})
	}

	/*如果对方条件不达标，就温和地返回错误，牵手失败*/
	if err = CheckIfGood(ta); err != nil {
		return
	}

	//计算幸福程度
	//fmt.Println("对方数据", ta.Height, ta.Rmb, ta.Looking,ta.Weight,ta.Age)
	happiness = (ta.Height * ta.Rmb * ta.Looking) / (ta.Weight * ta.Age)
	return

}
func NewHuman(name string, age, height, weight, rmb, looking, targetLooking float64, sex, targetSex Gender) *Human {
	h := new(Human)
	h.Name = name
	h.Age = age
	h.Height, h.Weight, h.Rmb, h.Looking, h.TargetLooking = height, weight, rmb, looking, targetLooking
	h.Sex, h.TargetSex = sex, targetSex

	//如果某些参数没有传，可以考虑在工厂中赋默认值

	return h
}

func main() {

	defer func() {
		/*如果性别不符，panic，在此处复活，擒获杀死老夫的元凶，也就是当初panic的数据*/
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()

	//cook := NewHuman("库克", 60, 180, 150, 1234567890, 60, 90, Male, Male)
	ySister := NewHuman("你妹", 20, 180, 150, 50, 99, 80, Female, Male)
	sicong := NewHuman("思聪", 30, 180, 150, 1234567890, 90, 99, Male, Female)

	//happiness, err := cook.Marry(ySister)
	happiness, err := ySister.Marry(sicong)

	if err != nil {
		fmt.Println("牵手失败，err=", err)
	} else {
		fmt.Println("牵手成功，幸福指数=", happiness)
	}
}
